<?php

namespace Caifenglei\AuthRbac\Http\Actions;

use Caifenglei\AuthRbac\Models\Permission;
use Caifenglei\AuthRbac\Models\Role;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
use Spatie\Permission\PermissionRegistrar;

class PermissionAction
{
    public static function createPermission($data){
        $perm_info = Arr::except($data, ['roles']);
        $permission = Permission::create($perm_info);
        if($roles = Arr::get($data, 'roles')) {
            if(is_numeric($roles[0])){
                $roles = Role::whereIn('id', $roles)->pluck('name');
            }
            $permission->assignRole($roles);
        }

        return $permission;
    }

    public static function deletePermissions(Permission $permission){

        $total_children = Permission::where('parent_id',$permission->id)->count();
        if($total_children > 0){
            throw new \Exception('该权限下存在子权限，请先删除子权限');
        }

        $permission->loadCount('roles');
        if($permission->roles_count > 0){
            throw new \Exception('该权限已赋予角色，不能删除');
        }

        $permission->delete();
    }

    public static function updatePermission($permission, $data) {
        $perm_info = Arr::except($data, ['roles']);
        $permission->update($perm_info);
        $roles = Arr::get($data, 'roles');
        if(!is_null($roles)) {
            if(count($roles) > 0){
                if(is_numeric($roles[0])){
                    $roles = Role::whereIn('id', $roles)->pluck('name');
                }
                $permission->syncRoles($roles);
            }else {
                $permission->syncRoles([]);
            }
        }
        return $permission;
    }

    /**
     * 根据路由，同步权限数据
     */
    public static function syncPermissions()
    {
        app()->make(PermissionRegistrar::class)->forgetCachedPermissions();
        $permissions = Permission::all();
        $named_permissions = [];
        foreach ($permissions as $permission) {
            $named_permissions[$permission->name] = $permission;
        }
        $route_collection = Route::getRoutes();

        //记录已同步的权限
        $synced = [];
        foreach ($route_collection as $route) {
            $route_name = $route->getName();
            $route_prefix = $route->getPrefix();

            if (!$route_name || !Str ::startsWith($route_prefix, 'api/') 
                || in_array($route_name, config('auth-rbac.authorized_free_routes'))) {
                continue;
            }

            $names = explode(Permission::NAME_SEPARATOR, $route_name);
            if (count($names) < 2) {
                continue;
            }
            $name_1 = $names[0];
            $name_2 = implode(Permission::NAME_SEPARATOR, [$names[0], $names[1]]);
            $lang_prefix = $name_1 === 'admin' ? 'auth-rbac::permission.' : 'permission.';

            //一级权限
            $label_key = $lang_prefix . $name_1 . '._label';
            if (!static::getValue($named_permissions, $name_1)) {
                if (array_key_exists($name_1, $synced)) {
                    $one = $synced[$name_1];
                } else {
                    $one = Permission::create([
                        'name' => $name_1,
                        'action' => $name_1,
                        'guard_name' => 'api',
                        'label' => __($label_key),
                        'type' => Permission::TYPE_BUTTON,
                        'parent_id' => 0
                    ]);
                    $synced[$name_1] = $one;
                }
            } else {
                $one = $named_permissions[$name_1];
                //未在lang中配置label，现在配置了，则更新
                if($one->label === $label_key && $label_key !== __($label_key)) {
                    $one->update([
                        'label' => __($label_key),
                    ]);
                }
            }

            //二级权限
            $label_key = $lang_prefix . $name_2 . '._label';
            if (!static::getValue($named_permissions, $name_2)) {
                if (array_key_exists($name_2, $synced)) {
                    $two = $synced[$name_2];
                } else {
                    $two = Permission::create([
                        'name' => $name_2,
                        'action' => $names[1],
                        'guard_name' => 'api',
                        'label' => __($label_key),
                        'type' => Permission::TYPE_BUTTON,
                        'parent_id' => $one->id
                    ]);
                    $synced[$name_2] = $two;
                }
            } else {
                $two = $named_permissions[$name_2];
                //未在lang中配置label，现在配置了，则更新
                if($two->label === $label_key && $label_key !== __($label_key)) {
                    $two->update([
                        'label' => __($label_key),
                    ]);
                }
            }

            //三级权限
            $label_key = $lang_prefix . $route_name;
            if(count($names) > 2) {
                if (!static::getValue($named_permissions, $route_name)) {
                    Permission::create([
                        'name' => $route_name,
                        'action' => $names[2],
                        'guard_name' => 'api',
                        'label' => __($label_key),
                        'type' => Permission::TYPE_BUTTON,
                        'parent_id' => $two->id
                    ]);
                }else{
                    $three = $named_permissions[$route_name];
                    //未在lang中配置label，现在配置了，则更新
                    if($three->label === $label_key && $label_key !== __($label_key)) {
                        $three->update([
                            'label' => __($label_key),
                        ]);
                    }
                }
            }
        }
    }

    /**
     * 为规避key的.特殊性
     */
    private static function getValue($collection, $key)
    {
        if (array_key_exists($key, $collection)) {
            return $collection[$key];
        }
        return null;
    }
}
